/*
   Copyright 2011-2012 gtalent2@gmail.com

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package world

import (
	"../entity"
	"../models"
	"github.com/gtalent/starfish/input"
	"runtime"
)

type UserKeyBindings struct {
	UpKey    int
	DownKey  int
	LeftKey  int
	RightKey int
}

var UserVi = UserKeyBindings{UpKey: input.Key_k, DownKey: input.Key_j, LeftKey: input.Key_h, RightKey: input.Key_l}
var UserViDvorak = UserKeyBindings{UpKey: input.Key_t, DownKey: input.Key_h, LeftKey: input.Key_d, RightKey: input.Key_n}
var UserWASD = UserKeyBindings{UpKey: input.Key_w, DownKey: input.Key_s, LeftKey: input.Key_a, RightKey: input.Key_d}
var UserWASD_Dvorak = UserKeyBindings{UpKey: input.Key_Comma, DownKey: input.Key_o, LeftKey: input.Key_a, RightKey: input.Key_e}

type User struct {
	MovableSprite
	person      *entity.Person
	UpKey       int
	DownKey     int
	LeftKey     int
	RightKey    int
	moving      bool
	movingUp    bool
	movingDown  bool
	movingLeft  bool
	movingRight bool
}

func NewUser(keys UserKeyBindings) *User {
	u := new(User)
	u.speed = 7
	u.UpKey = keys.UpKey
	u.DownKey = keys.DownKey
	u.LeftKey = keys.LeftKey
	u.RightKey = keys.RightKey
	return u
}

func LoadUser(ls *models.Sprite) *User {
	u := NewUser(UserWASD)
	loadMovableSprite(ls, &u.MovableSprite)
	return u
}

func (me *User) move() {
	me.lock()
	if me.moving {
		me.unlock()
		return
	}
	me.moving = true
	me.unlock()
	for {
		switch {
		case me.movingUp:
			me.MoveUp()
			break
		case me.movingDown:
			me.MoveDown()
			break
		case me.movingLeft:
			me.MoveLeft()
			break
		case me.movingRight:
			me.MoveRight()
			break
		default:
			me.moving = false
			return
		}
		runtime.Gosched()
	}
}

func (me *User) KeyPress(e input.KeyEvent) {
	if me.zone.world.pause.paused {
		return
	}
	switch e.Key {
	case me.UpKey:
		me.movingUp = true
		me.move()
	case me.DownKey:
		me.movingDown = true
		me.move()
	case me.LeftKey:
		me.movingLeft = true
		me.move()
	case me.RightKey:
		me.movingRight = true
		me.move()
	}
}

func (me *User) KeyRelease(e input.KeyEvent) {
	switch e.Key {
	case me.UpKey:
		me.movingUp = false
	case me.DownKey:
		me.movingDown = false
	case me.LeftKey:
		me.movingLeft = false
	case me.RightKey:
		me.movingRight = false
	}
}
